﻿using DrawableObjects.Actors;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Microsoft.Xna.Framework;
using Sirian.DrawableObject.Actors;
using GlobalGameClasses;

namespace SirianTestEnvironment
{
    /// <summary>
    ///Dies ist eine Testklasse für "ActorTest" und soll
    ///alle ActorTest Komponententests enthalten.
    ///</summary>
    [TestClass()]
    public class ActorTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Ruft den Testkontext auf, der Informationen
        ///über und Funktionalität für den aktuellen Testlauf bietet, oder legt diesen fest.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Zusätzliche Testattribute
        // 
        //Sie können beim Verfassen Ihrer Tests die folgenden zusätzlichen Attribute verwenden:
        //
        //Mit ClassInitialize führen Sie Code aus, bevor Sie den ersten Test in der Klasse ausführen.
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Mit ClassCleanup führen Sie Code aus, nachdem alle Tests in einer Klasse ausgeführt wurden.
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Mit TestInitialize können Sie vor jedem einzelnen Test Code ausführen.
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Mit TestCleanup können Sie nach jedem einzelnen Test Code ausführen.
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        

        internal virtual Actor CreateActor1()
        {
            Matrix world = Matrix.CreateWorld(new Vector3(0, 0, 0), Vector3.Down, Vector3.Up);
            Actor aircraft = DrawableObjects.Actors.Aircrafts.FabricatableAircraft.GET_ENEMY_1(world);
            return aircraft;
        }

        internal virtual Actor CreateActor2()
        {
            Actor projectile = DrawableObjects.Actors.Projectiles.Plasma.GET_PLASMA_LEVEl1();
            return projectile;
        }

        internal virtual Actor CreateActor3()
        {
            Actor item = DrawableObjects.Actors.Weapons.WeaponUpgrade.GET_UPGRADEITEM(
                DrawableObjects.Actors.Weapons.Weapon.WeaponType.Laser);
            return item;
        }

        /// <summary>
        ///Ein Test für "Initialize"
        ///</summary>
        [TestMethod()]
        public void InitializeTest()
        {
            Actor target1 = CreateActor1();
            Actor target2 = CreateActor2();
            Actor target3 = CreateActor3();
            try
            {
                target1.Initialize();
                target2.Initialize();
                target3.Initialize();
            }
            catch (ArgumentException)
            {
                //nop
            }
            Assert.IsTrue(target1.boundingSphereFactor > 0);
            Vector3 trans1 = target1.worldMatrix.Translation;            
            Assert.IsTrue(trans1.X == 0);
            Assert.IsTrue(trans1.Z == 0);
            Assert.IsTrue(target2.boundingSphereFactor > 0);
            Vector3 trans2 = target2.worldMatrix.Translation;          
            Assert.IsTrue(trans2.X == 0);
            Assert.IsTrue(trans2.Z == 0);
            Assert.IsTrue(target3.boundingSphereFactor > 0);
            Vector3 trans3 = target3.worldMatrix.Translation;            
            Assert.IsTrue(trans3.X == 0);
            Assert.IsTrue(trans3.Z == 0);
        }

        /// <summary>
        ///Ein Test für "Update"
        ///</summary>
        [TestMethod()]
        public void UpdateTest()
        {
            int updateRate = 166666;
            GlobalGameClasses.GlobalGameValues.Values.gameTime = new GameTime(new TimeSpan(updateRate), new TimeSpan(updateRate));
            Bounding bound = new Bounding(new Vector2(-400, -400), 800, 800, false);
            Actor target = CreateActor1();
            target.worldBounding = bound;
            target.speed = 300;
            target.moveInDirection(new Vector2(2,0));
            target.Update();
            Vector3 trans = target.worldMatrix.Translation;           
            Assert.IsTrue(trans.X >= 2);
            Assert.IsTrue(trans.Z == 0);
        }

        /// <summary>
        ///Ein Test für "isInBoundings"
        ///</summary>
        [TestMethod()]
        public void isInBoundingsTest()
        {
            Actor target1 = CreateActor1();
            Actor target2 = CreateActor2();
            Bounding bound = new Bounding(new Vector2(-100, -100), 200, 200, false);
            target1.worldBounding = bound;
            target2.worldBounding = bound;
            bool expected = true;       
            bool actual1;
            bool actual2;
            actual1 = target1.isInBoundings();
            actual2 = target2.isInBoundings();
            Assert.AreEqual(expected, actual1);
            Assert.AreEqual(expected, actual2);
        }

        /// <summary>
        ///Ein Test für "moveInDirection"
        ///</summary>
        [TestMethod()]
        public void moveInDirectionTest()
        {
            int updateRate = 166666;
            GlobalGameClasses.GlobalGameValues.Values.gameTime = new GameTime(new TimeSpan(updateRate), new TimeSpan(updateRate));
            Bounding bound = new Bounding(new Vector2(-400, -400), 800, 800, false);
            Actor target = CreateActor1();
            target.worldBounding = bound;
            target.speed = 10;
            Vector2 direction = new Vector2(2, 2);
            target.moveInDirection(direction);
            target.Update();
            Vector3 trans = target.worldMatrix.Translation; 
            Assert.IsTrue(trans.X >= 2);
            Assert.IsTrue(trans.Z >= 2);
            Assert.IsTrue(trans.X == trans.Z);
        }

        /// <summary>
        ///Ein Test für "moveTowards"
        ///</summary>
        [TestMethod()]
        public void moveTowardsTest()
        {
            int updateRate = 166666;
            GlobalGameClasses.GlobalGameValues.Values.gameTime = new GameTime(new TimeSpan(updateRate), new TimeSpan(updateRate));
            Bounding bound = new Bounding(new Vector2(-400, -400), 800, 800, false);
            Actor target = CreateActor1();
            target.worldBounding = bound;
            target.speed = 1;
            Vector2 direction = new Vector2(2, 0);
            target.moveInDirection(direction);
            target.Update();
            Vector3 trans = target.worldMatrix.Translation;
            Assert.IsTrue(trans.X >= 1);
            Assert.IsTrue(trans.Z == 0);
        }
    }
}
